/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	ComponentLight.cpp
*
*	Comments	-	See ComponentLight.h
*
**************************************************************************************/
#include "../Include/ComponentLight.h"
#include "../Include/Engine.h"
#include "../Include/Actor.h"
#include "../Include/EventRender.h"
#include "../Include/EventTransform.h"
#include "../Include/RenderEntryLight.h"
#include "../Include/GlobalGraphicsStrings.h"
#include "../Include/ParameterBinderScalar.h"

namespace Pulse
{
	ComponentLight::ComponentLight( Actor *pOwner ) 
		: IComponent( pOwner )
	{

	}

	ComponentLight::~ComponentLight( void )
	{
		m_pOwner->RemoveListener( EEvent::RENDER, this, &ComponentLight::OnRender );
	}

	EErrorCode::Type ComponentLight::Initialize( XMLElementPtr pElem )
	{
		RenderPathForwardPlus *pRenderPath = Engine::GetInstance()->GetRenderer()->GetRenderPath();

		// Add parameter binders
		{
			ParameterSystem *pParamSys = Engine::GetInstance()->GetRenderer()->GetParameterSystem();
			IParameter *pParam;
			IParameterBinder *pBinder;
			
			// World transform binder
			pParam = pParamSys->GetMatrix( GFX_PARAM_TRANSFORM_WORLD );
			pBinder = m_light.AddParameter( pParam );
			pBinder->SetAsMatrix( GetOwnerUnsafe()->GetTransformWorld() );
		
			// type

			// color
			pParam = pParamSys->GetVector3( GFX_PARAM_LIGHT_COLOR );
			m_pBinderColor = (ParameterBinderVector3*)m_light.AddParameter( pParam );
			m_pBinderColor->SetAsVector3( m_light.GetColor() );

			// range
			pParam = pParamSys->GetScalar( GFX_PARAM_LIGHT_RANGE );
			m_pBinderRange = (ParameterBinderScalar*)m_light.AddParameter( pParam );
			m_pBinderRange->SetAsScalar( m_light.GetRange() );
			
			// inner spot angle
			pParam = pParamSys->GetScalar( GFX_PARAM_LIGHT_SPOT_INNER );
			m_pBinderSpotInner = (ParameterBinderScalar*)m_light.AddParameter( pParam );
			m_pBinderSpotInner->SetAsScalar( m_light.GetInnerAngle() );

			// outer spot angle
			pParam = pParamSys->GetScalar( GFX_PARAM_LIGHT_SPOT_OUTER );
			m_pBinderSpotOuter = (ParameterBinderScalar*)m_light.AddParameter( pParam );
			m_pBinderSpotOuter->SetAsScalar( m_light.GetOuterAngle() );
		}

		// NOTE: Creating the render entries are optional depending on the render path configuration.
		{
			EErrorCode::Type retCode = pRenderPath->BuildRenderEntries( this );

			if ( retCode != EErrorCode::OKAY )
			{
				return retCode;
			}
		}

		// Add delegates
		m_pOwner->AddListener( EEvent::RENDER, this, &ComponentLight::OnRender );

		return EErrorCode::OKAY;
	}

	void ComponentLight::SetLightType( ELight::Type type ) 
	{
		m_light.SetType( type ); 
	}

	void ComponentLight::SetColor( const Vector3 *pColor ) 
	{
		m_light.SetColor( pColor ); 
		m_pBinderColor->SetAsVector3( pColor ); 
	}

	void ComponentLight::SetRange( const FLOAT range ) 
	{ 
		m_light.SetRange( range );
		m_pBinderRange->SetAsScalar( range ); 
	}

	void ComponentLight::SetInnerAngle( const FLOAT innerAngle ) 
	{
		m_light.SetInnerAngle( innerAngle ); 
		m_pBinderSpotInner->SetAsScalar( innerAngle ); 
	}

	void ComponentLight::SetOuterAngle( const FLOAT outerAngle ) 
	{
		m_light.SetOuterAngle( outerAngle ); 
		m_pBinderSpotOuter->SetAsScalar( outerAngle );
	}

	void ComponentLight::OnRender( IEvent *pEvent )
	{
		EventRender *pRenderEvent = (EventRender*)pEvent;
		SIZE_T numEntries = m_renderEntries.GetNumEntries();
		
		//if ( numEntries )
		//{
		//	//pRenderEvent->GetCamera()->;

		//	RenderEntry **pEntries = m_renderEntries.GetRenderEntries();
		//	
		//	for ( SIZE_T i = 0; i < numEntries; ++i )
		//	{
		//		pRenderEvent->GetRenderView()->AddRenderEntry( pEntries[i] );
		//	}
		//}
		//else
		//{
		//	// Lights are gathered in a separate container for further
		//	//	processing later in the render stages.
		//	pRenderEvent->GetRenderView()->AddLight( this );
		//}

		pRenderEvent->GetRenderView()->AddLight( this );

	}

	void ComponentLight::OnTransform( IEvent *pEvent )
	{
		EventTransform *pTransform = (EventTransform*)pEvent;

		//if ( pTransform->GetEventOwner() == this )
		//{
		//	//m_pModel->SetTransform( pTransform->GetTransform() );
		//}

		pTransform->GetTransform()->GetTranslation();
	}


}